﻿
using Cl.Entity.BaseEntity;
using Cl.Entity.DataBaseEntity.Goods;
using Cl.Entity.DataBaseEntity.Orders;
using Cl.Entity.DataBaseEntity.Shops;
using Cl.Entity.DataBaseEntity.System;
using Cl.Entity.DataBaseEntity.Test;
using Cl.Entity.DataBaseEntity.User;
using Cl.Utils.Primitives.Enum;
using log4net.Filter;
using Microsoft.Data.SqlClient;
using SqlSugar;
using SqlSugar.IOC;
using System.Reflection;

namespace Cl.Repository.Sqlsugar
{
    public class AppDbContext
    {
        public SqlSugarClient Db;
        public AppDbContext(string connectionString, string dbType)
        {

            #region 数据库连接PlanA（用来外放访问，自动创建库和表）

            Db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = connectionString,// "server=.;database=StudentDb;uid=sa;pwd=123;"
                DbType = GetDbType(dbType),// DbType.SqlServer,//设置数据库类型
                IsAutoCloseConnection = true,//自动释放数据库，如果存在事务，在事务结束之后释放。
                InitKeyType = InitKeyType.Attribute,//从实体特性中读取主键自增列信息   
                ConfigureExternalServices = new ConfigureExternalServices
                {
                    //注意:  这儿AOP设置不能少
                    EntityService = (c, p) =>
                    {
                        /***低版本C#写法***/
                        // int?  decimal?这种 isnullable=true 不支持string(下面.NET 7支持)
                        if (p.IsPrimarykey == false && c.PropertyType.IsGenericType &&
                        c.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                        {
                            p.IsNullable = true;
                        }

                        /***高版C#写法***/
                        //if (p.IsPrimarykey == false && new NullabilityInfoContext()
                        // .Create(c).WriteState is NullabilityState.Nullable)
                        //{
                        //    p.IsNullable = true;
                        //}
                    }
                }
            },
            filterDB =>
            {
                //符合条件执行过滤器
                filterDB.QueryFilter.AddTableFilter<IDeleted>(it => it.DeleteTime == null);

                //过滤器写在这儿
                //Db.QueryFilter.AddTableFilter<IDeleted>(it => it.DeleteTime == null);
            });
            Db.Aop.OnLogExecuting = (sql, pars) =>
            {
                Console.WriteLine(sql + "\r\n" + Db.Utilities.SerializeObject
                    (pars.ToDictionary(it => it.ParameterName, it => it.Value)));
                Console.WriteLine();
            };

            #endregion

            #region 数据库连接PlanB（用来Ioc注入方法，仓储模式使用）

            SugarIocServices.AddSqlSugar(new IocConfig()
            {
                ConnectionString = connectionString,
                DbType = GetIocDbType(dbType),
                IsAutoCloseConnection = true,
            });
            SugarIocServices.ConfigurationSugar(configDb =>
            {
                configDb.CurrentConnectionConfig.InitKeyType = InitKeyType.Attribute;
                configDb.CurrentConnectionConfig.ConfigureExternalServices = new ConfigureExternalServices()
                {
                    //注意:  这儿AOP设置不能少
                    EntityService = (c, p) =>
                    {
                        /***低版本C#写法***/
                        // int?  decimal?这种 isnullable=true 不支持string(下面.NET 7支持)
                        if (p.IsPrimarykey == false && c.PropertyType.IsGenericType &&
                        c.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                        {
                            p.IsNullable = true;
                        }
                    }
                };
                configDb.Aop.OnLogExecuted = (sql, pars) =>
                {
                    Console.WriteLine(sql + "\r\n" + Db.Utilities.SerializeObject
                       (pars.ToDictionary(it => it.ParameterName, it => it.Value)));
                    Console.WriteLine();
                };
                //符合条件执行过滤器
                configDb.QueryFilter.AddTableFilter<IDeleted>(it => it.DeleteTime == null);
            });
            #endregion


        }

        private IocDbType GetIocDbType(string dbType)
        {
            IocDbType result = IocDbType.MySql;
            switch (dbType)
            {
                case "1":
                    result = IocDbType.MySql;
                    break;
                case "2":
                    result = IocDbType.SqlServer;
                    break;
                case "3":
                    result = IocDbType.Sqlite;
                    break;
            }
            return result;
        }

        private DbType GetDbType(string dbType)
        {
            DbType result = DbType.MySql;
            switch (dbType)
            {
                case "1":
                    result = DbType.MySql;
                    break;
                case "2":
                    result = DbType.SqlServer;
                    break;
                case "3":
                    result = DbType.Sqlite;
                    break;
            }
            return result;
        }

        public void CreateTable(bool Backup = false, int StringDefaultLength = 50, params Type[] types)
        {
            types = new Type[] {

                typeof(Department),
                typeof(Permission),

                typeof(User),
                typeof(UserDepartment),
                typeof(UserRole),
                typeof(UserApproFlowMap),

                typeof(Role),
                typeof(RoleDepartment),
                typeof(RolePermission),

                typeof(UserLogin),
                typeof(TemplateDemo),

                typeof(LoginLog),
                typeof(OperationLog),
                typeof(UserHistory),
                
                //typeof(Company),
                
                typeof(BaseGoods),
                typeof(GoodsGroup),
                typeof(BaseShop),

                typeof(GoodsOrder),
                typeof(GoodsOrderRelatedGoods),

            };

            //Db.CodeFirst.SetStringDefaultLength(StringDefaultLength);
            Db.DbMaintenance.CreateDatabase();
            if (Backup)
            {

                Db.CodeFirst.SetStringDefaultLength(StringDefaultLength).BackupTable().InitTables(types);
            }
            else
            {
                Db.CodeFirst.SetStringDefaultLength(StringDefaultLength).InitTables(types);
            }

            #region 初始化 菜单数据


            if (Db.Queryable<Department>().Count() <= 0)
            {
                var Department = new Department() { Code = "xunpaikeji", Name = "讯湃科技", ParentId = null, Enabled = true, Description = "", MemberCount = 0, Sort = 1, Value = "" };
                var DepartmentId = Db.Insertable(Department).ExecuteReturnIdentity();

                var Department1 = new Department() { Code = "", Name = "开发部", ParentId = DepartmentId, Enabled = true, Description = "", MemberCount = 0, Sort = 1, Value = "" };
                var Department1Id = Db.Insertable(Department1).ExecuteReturnIdentity();
                var Department2 = new Department() { Code = "", Name = "销售部", ParentId = DepartmentId, Enabled = true, Description = "", MemberCount = 0, Sort = 1, Value = "" };
                Db.Insertable(Department2).ExecuteReturnIdentity();
                var Department3 = new Department() { Code = "", Name = "财务部", ParentId = DepartmentId, Enabled = true, Description = "", MemberCount = 0, Sort = 1, Value = "" };
                Db.Insertable(Department3).ExecuteReturnIdentity();

                var Department11 = new Department() { Code = "", Name = "产品小组", ParentId = Department1Id, Enabled = true, Description = "", MemberCount = 0, Sort = 1, Value = "" };
                Db.Insertable(Department11).ExecuteReturnIdentity();
                var Department12 = new Department() { Code = "", Name = "测试小组", ParentId = Department1Id, Enabled = true, Description = "", MemberCount = 0, Sort = 1, Value = "" };
                Db.Insertable(Department12).ExecuteReturnIdentity();



            }

            if (Db.Queryable<Role>().Count() <= 0)
            {
                var role = new Role() { Code = "xitongmoren", Name = "系统默认", ParentId = null, Type = RoleType.Group, Sort = 1, Hidden = false, DataScope = DataScope.All, Description = "" };
                var roleId = Db.Insertable(role).ExecuteReturnIdentity();
                var role1 = new Role() { Code = "jishubu", Name = "超级管理员", ParentId = roleId, Type = RoleType.Role, Sort = 1, Hidden = false, DataScope = DataScope.All, Description = "" };
                Db.Insertable(role1).ExecuteReturnIdentity();

                var role2 = new Role() { Code = "岗位", Name = "岗位", ParentId = null, Type = RoleType.Group, Sort = 2, Hidden = false, DataScope = DataScope.All, Description = "" };
                var role2Id = Db.Insertable(role2).ExecuteReturnIdentity();
                var role3 = new Role() { Code = "shangweiji", Name = "上位机", ParentId = roleId, Type = RoleType.Role, Sort = 1, Hidden = false, DataScope = DataScope.All, Description = "" };
                var role4 = new Role() { Code = "jishubu", Name = "嵌入式", ParentId = roleId, Type = RoleType.Role, Sort = 2, Hidden = false, DataScope = DataScope.All, Description = "" };

                Db.Insertable(role3).ExecuteReturnIdentity();
                Db.Insertable(role4).ExecuteReturnIdentity();
            }


            if (Db.Queryable<User>().Count() <= 0)
            {
                //PWD :123456
                var adminUser = new User() { Account = "ChaoJiAdmin", CreateId = 0, CreateTime = DateTime.Now, DepartmentId = 0, IsEnable = 1, PassWord = "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92", UserName = "ChaoJiAdmin" };
                var userId = Db.Insertable(adminUser).ExecuteReturnIdentity();
            }

            if (Db.Queryable<Permission>().Count() <= 0)
            {
                var console = new Permission()
                {
                    Label = "工作台",
                    Name = "工作台",
                    Code = "console",
                    ParentId = null,
                    CreateId = 1,
                    CreateTime = DateTime.Now,
                    Description = "",
                    Enabled = true,
                    Hidden = false,
                    Icon = "",
                    IsAffix = false,
                    IsIframe = false,
                    Link = "",
                    NewWindow = false,
                    Opened = false,
                    Path = "",
                    Redirect = "",
                    Sort = 1,
                    Type = PermissionType.Menu,
                    ViewId = null,
                };
                Db.Insertable(console).ExecuteReturnIdentity();

                var Authority = new Permission()
                {
                    Label = "权限管理",
                    Name = "权限管理",
                    Code = "Authority",
                    ParentId = null,
                    Type = PermissionType.Group,
                    CreateId = 1,
                    CreateTime = DateTime.Now,
                    Description = "",
                    Enabled = true,
                    Hidden = false,
                    Icon = "",
                    IsAffix = false,
                    IsIframe = false,
                    Link = "",
                    NewWindow = false,
                    Opened = false,
                    Path = "",
                    Redirect = "",
                    Sort = 1,
                    ViewId = null,
                };
                var AuthorityId = Db.Insertable(Authority).ExecuteReturnIdentity();
                //用户  角色 部门 权限

                var user = new Permission()
                {
                    Label = "用户管理",
                    Name = "用户管理",
                    Code = "user",
                    ParentId = AuthorityId,
                    Type = PermissionType.Menu,
                    CreateId = 1,
                    CreateTime = DateTime.Now,
                    Description = "",
                    Enabled = true,
                    Hidden = false,
                    Icon = "",
                    IsAffix = false,
                    IsIframe = false,
                    Link = "",
                    NewWindow = false,
                    Opened = false,
                    Path = "",
                    Redirect = "",
                    Sort = 1,
                    ViewId = null,
                };
                Db.Insertable(user).ExecuteReturnIdentity();

                var role = new Permission()
                {
                    Label = "角色管理",
                    Name = "角色管理",
                    Code = "role",
                    ParentId = AuthorityId,
                    Type = PermissionType.Menu,
                    CreateId = 1,
                    CreateTime = DateTime.Now,
                    Description = "",
                    Enabled = true,
                    Hidden = false,
                    Icon = "",
                    IsAffix = false,
                    IsIframe = false,
                    Link = "",
                    NewWindow = false,
                    Opened = false,
                    Path = "",
                    Redirect = "",
                    Sort = 1,
                    ViewId = null,
                };
                Db.Insertable(role).ExecuteReturnIdentity();

                var org = new Permission()
                {
                    Label = "部门管理",
                    Name = "部门管理",
                    Code = "org",
                    ParentId = AuthorityId,
                    Type = PermissionType.Menu,
                    CreateId = 1,
                    CreateTime = DateTime.Now,
                    Description = "",
                    Enabled = true,
                    Hidden = false,
                    Icon = "",
                    IsAffix = false,
                    IsIframe = false,
                    Link = "",
                    NewWindow = false,
                    Opened = false,
                    Path = "",
                    Redirect = "",
                    Sort = 1,
                    ViewId = null,
                };
                Db.Insertable(org).ExecuteReturnIdentity();

                var AuthorityInfo = new Permission()
                {
                    Label = "权限管理",
                    Name = "权限管理",
                    Code = "AuthorityInfo",
                    ParentId = AuthorityId,
                    Type = PermissionType.Menu,
                    CreateId = 1,
                    CreateTime = DateTime.Now,
                    Description = "",
                    Enabled = true,
                    Hidden = false,
                    Icon = "",
                    IsAffix = false,
                    IsIframe = false,
                    Link = "",
                    NewWindow = false,
                    Opened = false,
                    Path = "",
                    Redirect = "",
                    Sort = 1,
                    ViewId = null,
                };
                Db.Insertable(AuthorityInfo).ExecuteReturnIdentity();
            }
            #endregion
        }


        //public SimpleClient<User> Users { get { return new SimpleClient<User>(Db); } }
        //public SimpleClient<AccountLogin> AccountLogins { get { return new SimpleClient<AccountLogin>(Db); } }
        //public SimpleClient<Template> Templates { get { return new SimpleClient<Template>(Db); } }

    }
}
